// **********************************************************
// *
// *  Copyright (c) 2003  SeikoEpson Inc
// *  All Rights Reserved
// *
// *  File name : f_FABS.S
// *  Function  :
// *      C Standard Library Function "sin"
// *      The "sin" function calculates the sine of x which is radian.
// *      This file is copied from math.lib of 
// *                  CC33 tool(CC33v40.exe + CCPA45.exe, 
// *                  math of ansilib33v25 )
// *
// *  original file's Revision  :
// *      1999/12/08  Created by H.Ishida
// *  Revision  :
// *      2003/04/09  IrumaSoft M.Takeishi   start
// *      2003/06/24  IrumaSoft M.Takeishi   changed for gnu33 and 
// *                                          got more paformance
// *
// **********************************************************/
//  --- Format of floating point (double precision) ---
// 
//   31|30         23|22                0
//    -----------------------------------
//   | |  exponent   |   fraction        |
//    -----------------------------------
//   |    8 bits     |    23 bits        |

// ==============================================================================
// 	Function: double fabs(double x)
// 
// 	Input:  %r6: Argument x in float.
// 
// 	Output: %r4: Return vlaue, absolute value of x in float.
// 

#include "f_mathf.def"

	.text
	.align	1
	.global	f_fabs

f_fabs:
// 
// 	Copy the input value in the register %r6
// 	to  the output value in the register %r4.
// 

	//  set the  value to be returned:
	ld.w	%r4,%r6		//  Copy input to output reg.
	sll		%r4,1		//  Shift to the left  by one bit.
	srl		%r4,1		//  Shift back to the right by one bit.


	//  Is argument NaN, +-INF or other?
	ld.w	%r12,%r4
	xld.w	%r11,0x7f800000
	and		%r12,%r11
	cmp		%r12,%r11
	jreq	IsNaNorINF

	//  returns normally
	ret

IsNaNorINF:

	xld.w	%r10, 0x7f800000
	cmp		%r4,%r10
	jrne	IsNaN
	xld.w	%r11, ERANGE
	xld.w	[ errno ], %r11
	xjp		ERR_END

IsNaN:
	xld.w	%r10, 0x7fc00000
	and		%r6,%r10
	cmp		%r6,%r10
	jrne	ERR_END
	xld.w	%r11, EDOM
	xld.w	[ errno ], %r11
	ld.w	%r4,%r10

ERR_END:
	ret
